package com.xxkk.spring_boot_web.util;

import org.springframework.stereotype.Component;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author xxkk
 * @version 1.0.0
 * @title ServerPool
 * @description ʕ•ᴥ•ʔ 服务线程池，执行线程任务使用
 * @create 2023/11/13 14:07
 **/
@Component
public class ServerPool implements Closeable {
    private ScheduledThreadPoolExecutor executor;
    public ScheduledThreadPoolExecutor getExecutor() {
        return executor;
    }

    @Override
    public void close() throws IOException {
        executor.shutdown();
    }

    public static class CustomThreadFactory implements ThreadFactory {
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;
        private final boolean daemon;
        private final int priority;

        public CustomThreadFactory(String namePrefix, boolean daemon, int priority) {
            this.namePrefix = namePrefix;
            this.daemon = daemon;
            this.priority = priority;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, namePrefix + "-thread-" + threadNumber.getAndIncrement());
            t.setDaemon(daemon);
            t.setPriority(priority);
            return t;
        }
    }

    private ServerPool() {
        CustomThreadFactory factory = new CustomThreadFactory("ServerPool", false, Thread.NORM_PRIORITY);
        this.executor = new ScheduledThreadPoolExecutor(1, factory);
    }

    private static volatile ServerPool instance = null;

    /**
     * 单例模式调用服务线程池
     * <pre>{@code
     * ServerPool.Ins().submit(()->{return false;});
     * }</pre>
     *
     * @return {@link ServerPool}
     */
    public static ServerPool Ins() {
        if (instance == null)
            synchronized (ServerPool.class) {
                if (instance == null)
                    instance = new ServerPool();
            }
        return instance;
    }

    public void execute(Runnable runnable) {
        executor.execute(runnable);
    }

    /**
     * 异步执行任务并等待返回结果
     *
     * <pre>{@code
     * future = submit((param_or_empty)->function_return)
     * try {
     *     future.get(time,timeUnit);
     *  } cache(){
     *     future.cancel(true);//future timeout
     *  }
     * } </pre>
     *
     * @param callable {@link Callable}
     * @return {@link Future}
     */
    public <T> Future<T> submit(Callable<T> callable) {
        return this.executor.submit(callable);
    }

    /**
     * 延时执行一次任务
     */
    public ScheduledFuture<?> schedule(Runnable runnable, long delay, TimeUnit unit) {
        return executor.schedule(runnable, delay, unit);
    }

    /**
     * 间隔时间重复执行任务
     */
    public ScheduledFuture<?> scheduleAtFixRate(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
        return executor.scheduleAtFixedRate(runnable, initialDelay, period, unit);
    }

    /**
     * 间隔时间重复执行任务
     */
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
        return executor.scheduleWithFixedDelay(runnable, initialDelay, period, unit);
    }


}
